using System.Text;
using System.Text.Json;

namespace DeviceDataGenerator
{
    /// <summary>
    /// 测试记录生成器
    /// 负责在测试结束后生成完整的测试记录说明文档
    /// </summary>
    public class TestRecordGenerator
    {
        private readonly string _recordsDirectory;
        private readonly PerformanceStats _stats;
        private readonly PerformanceTestSettings _settings;
        private readonly DateTime _testStartTime;

        public TestRecordGenerator(PerformanceStats stats, PerformanceTestSettings settings, DateTime testStartTime)
        {
            _stats = stats;
            _settings = settings;
            _testStartTime = testStartTime;
            _recordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestRecords");
            
            // 确保目录存在
            Directory.CreateDirectory(_recordsDirectory);
        }

        /// <summary>
        /// 生成完整的测试记录报告
        /// </summary>
        /// <returns>生成的文件路径</returns>
        public string GenerateTestRecord()
        {
            var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            var fileName = $"TestRecord_{timestamp}.md";
            var filePath = Path.Combine(_recordsDirectory, fileName);

            var content = GenerateMarkdownContent();
            File.WriteAllText(filePath, content, Encoding.UTF8);

            // 同时生成JSON格式的详细数据
            GenerateJsonReport(timestamp);

            return filePath;
        }

        /// <summary>
        /// 生成Markdown格式的测试记录内容
        /// </summary>
        private string GenerateMarkdownContent()
        {
            var sb = new StringBuilder();
            var testEndTime = DateTime.Now;
            var totalRunTime = testEndTime - _testStartTime;

            // 文档头部
            sb.AppendLine("# DeviceCommons 性能测试记录报告");
            sb.AppendLine();
            sb.AppendLine($"**生成时间**: {testEndTime:yyyy年MM月dd日 HH:mm:ss}");
            sb.AppendLine($"**测试开始时间**: {_testStartTime:yyyy年MM月dd日 HH:mm:ss}");
            sb.AppendLine($"**测试结束时间**: {testEndTime:yyyy年MM月dd日 HH:mm:ss}");
            sb.AppendLine($"**总运行时长**: {FormatTimeSpan(totalRunTime)}");
            sb.AppendLine();

            // 测试配置信息
            AppendTestConfiguration(sb);

            // 总体测试结果
            AppendOverallResults(sb);

            // 系统资源统计
            AppendSystemResourceStats(sb);

            // 数据大小分段统计
            AppendSegmentedAnalysis(sb);

            // 结论和建议
            AppendConclusionsAndRecommendations(sb);

            return sb.ToString();
        }

        /// <summary>
        /// 添加测试配置信息
        /// </summary>
        private void AppendTestConfiguration(StringBuilder sb)
        {
            sb.AppendLine("## 📋 测试配置信息");
            sb.AppendLine();
            sb.AppendLine("| 配置项 | 值 |");
            sb.AppendLine("|-------|-----|");
            sb.AppendLine($"| 测试模式 | {GetTestModeName()} |");
            sb.AppendLine($"| 加密概率 | {_settings.Test.EncryptionProbability:P0} |");
            sb.AppendLine($"| 压缩概率 | {_settings.Test.CompressionProbability:P0} |");
            sb.AppendLine($"| 测试间隔 | {_settings.Test.IntervalMs} ms |");
            sb.AppendLine($"| 设备读数范围 | {_settings.DataGeneration.ReadingCountRange.Min} - {_settings.DataGeneration.ReadingCountRange.Max} |");
            sb.AppendLine($"| 设备状态范围 | {_settings.DataGeneration.StateCountRange.Min} - {_settings.DataGeneration.StateCountRange.Max} |");
            sb.AppendLine($"| 显示更新间隔 | {_settings.Display.UpdateIntervalMs} ms |");
            sb.AppendLine();
        }

        /// <summary>
        /// 添加总体测试结果
        /// </summary>
        private void AppendOverallResults(StringBuilder sb)
        {
            sb.AppendLine("## 📊 总体测试结果");
            sb.AppendLine();
            sb.AppendLine("### 基本统计");
            sb.AppendLine("| 指标 | 数值 |");
            sb.AppendLine("|-----|------|");
            sb.AppendLine($"| 总测试次数 | {_stats.TotalTests:N0} |");
            sb.AppendLine($"| 成功测试次数 | {_stats.SuccessCount:N0} |");
            sb.AppendLine($"| 测试成功率 | {_stats.SuccessRate:P2} |");
            sb.AppendLine($"| 平均吞吐量 | {_stats.TestsPerSecond:F1} 测试/秒 |");
            sb.AppendLine();

            sb.AppendLine("### 性能汇总");
            sb.AppendLine("| 操作 | 平均时间 | 移动平均 | 最小时间 | 最大时间 |");
            sb.AppendLine("|-----|---------|---------|---------|---------|");
            sb.AppendLine($"| 构建 | {_stats.AverageBuildTime:F3} ms | {_stats.MovingAverageBuildTime:F3} ms | {_stats.MinBuildTime:F3} ms | {_stats.MaxBuildTime:F3} ms |");
            sb.AppendLine($"| 序列化 | {_stats.AverageSerializeTime:F3} ms | {_stats.MovingAverageSerializeTime:F3} ms | {_stats.MinSerializeTime:F3} ms | {_stats.MaxSerializeTime:F3} ms |");
            sb.AppendLine($"| 解析 | {_stats.AverageParseTime:F3} ms | {_stats.MovingAverageParseTime:F3} ms | {_stats.MinParseTime:F3} ms | {_stats.MaxParseTime:F3} ms |");
            sb.AppendLine();

            // 加密压缩对比
            if (_stats.EncryptedCount > 0 && _stats.UnencryptedCount > 0)
            {
                sb.AppendLine("### 🔐 加密性能影响");
                sb.AppendLine("| 指标 | 加密 | 不加密 | 差异 |");
                sb.AppendLine("|-----|------|--------|------|");
                sb.AppendLine($"| 测试次数 | {_stats.EncryptedCount:N0} | {_stats.UnencryptedCount:N0} | - |");
                sb.AppendLine($"| 平均耗时 | {_stats.EncryptedAverageTime:F3} ms | {_stats.UnencryptedAverageTime:F3} ms | +{_stats.EncryptionOverhead:F3} ms |");
                sb.AppendLine($"| 性能开销 | - | - | {(_stats.EncryptionOverhead / _stats.UnencryptedAverageTime * 100):F1}% |");
                sb.AppendLine();
            }

            if (_stats.CompressedCount > 0 && _stats.UncompressedCount > 0)
            {
                sb.AppendLine("### 🗜️ 压缩性能影响");
                sb.AppendLine("| 指标 | 压缩 | 不压缩 | 差异 |");
                sb.AppendLine("|-----|------|--------|------|");
                sb.AppendLine($"| 测试次数 | {_stats.CompressedCount:N0} | {_stats.UncompressedCount:N0} | - |");
                sb.AppendLine($"| 平均耗时 | {_stats.CompressedAverageTime:F3} ms | {_stats.UncompressedAverageTime:F3} ms | +{_stats.CompressionOverhead:F3} ms |");
                sb.AppendLine($"| 性能开销 | - | - | {(_stats.CompressionOverhead / _stats.UncompressedAverageTime * 100):F1}% |");
                sb.AppendLine($"| 平均消息大小 | {_stats.CompressedAverageSize:F0} 字符 | {_stats.UncompressedAverageSize:F0} 字符 | 压缩比 {((1 - _stats.CompressedAverageSize / _stats.UncompressedAverageSize) * 100):F1}% |");
                sb.AppendLine();
            }
        }

        /// <summary>
        /// 添加系统资源统计
        /// </summary>
        private void AppendSystemResourceStats(StringBuilder sb)
        {
            sb.AppendLine("## 💾 系统资源统计");
            sb.AppendLine();
            sb.AppendLine("### CPU 使用率");
            sb.AppendLine("| 统计类型 | 数值 |");
            sb.AppendLine("|---------|------|");
            sb.AppendLine($"| 平均CPU使用率 | {_stats.AverageCpuUsage:F1}% |");
            sb.AppendLine($"| 千次移动平均 | {_stats.MovingAverageCpuUsage:F1}% |");
            sb.AppendLine($"| 最小CPU使用率 | {_stats.MinCpuUsage:F1}% |");
            sb.AppendLine($"| 最大CPU使用率 | {_stats.MaxCpuUsage:F1}% |");
            sb.AppendLine();

            sb.AppendLine("### 内存使用量");
            sb.AppendLine("| 统计类型 | 数值 |");
            sb.AppendLine("|---------|------|");
            sb.AppendLine($"| 平均内存使用 | {_stats.AverageMemoryUsageMB:F1} MB |");
            sb.AppendLine($"| 千次移动平均 | {_stats.MovingAverageMemoryUsageMB:F1} MB |");
            sb.AppendLine($"| 最小内存使用 | {_stats.MinMemoryUsageMB:F1} MB |");
            sb.AppendLine($"| 最大内存使用 | {_stats.MaxMemoryUsageMB:F1} MB |");
            sb.AppendLine();
        }

        /// <summary>
        /// 添加数据大小分段统计
        /// </summary>
        private void AppendSegmentedAnalysis(StringBuilder sb)
        {
            sb.AppendLine("## 📈 数据大小分段统计与加密压缩对比");
            sb.AppendLine();
            
            var segmentStats = _stats.GetParseTimeSegmentStats().ToList();
            if (!segmentStats.Any())
            {
                sb.AppendLine("暂无分段统计数据。");
                sb.AppendLine();
                return;
            }

            sb.AppendLine("### 分段基本统计");
            sb.AppendLine("| 分段 | 测试次数 | 平均解析时间 | 移动平均 | 吞吐量 | 平均数据大小 |");
            sb.AppendLine("|-----|---------|-------------|---------|--------|-------------|");
            
            foreach (var segment in segmentStats)
            {
                sb.AppendLine($"| {segment.SegmentName} | {segment.Count:N0} | {segment.AverageParseTime:F3} ms | {segment.MovingAverageParseTime:F3} ms | {segment.ThroughputKBps:F1} KB/s | {segment.AverageDataSize:F0} 字节 |");
            }
            sb.AppendLine();

            // 各分段详细分析
            foreach (var segment in segmentStats)
            {
                sb.AppendLine($"### {segment.SegmentName} 详细分析");
                sb.AppendLine();

                // 加密对比
                if (segment.EncryptedCount > 0 && segment.UnencryptedCount > 0)
                {
                    sb.AppendLine("#### 🔐 加密状态对比");
                    sb.AppendLine("| 状态 | 测试次数 | 平均时间 | 移动平均 | 吞吐量 | 开销 |");
                    sb.AppendLine("|-----|---------|---------|---------|--------|------|");
                    sb.AppendLine($"| 加密 | {segment.EncryptedCount:N0} | {segment.EncryptedAverageParseTime:F3} ms | {segment.EncryptedMovingAverageParseTime:F3} ms | {segment.EncryptedThroughputKBps:F1} KB/s | - |");
                    sb.AppendLine($"| 不加密 | {segment.UnencryptedCount:N0} | {segment.UnencryptedAverageParseTime:F3} ms | {segment.UnencryptedMovingAverageParseTime:F3} ms | {segment.UnencryptedThroughputKBps:F1} KB/s | - |");
                    sb.AppendLine($"| **差异** | - | **+{segment.EncryptionOverhead:F3} ms** | - | **-{(segment.UnencryptedThroughputKBps - segment.EncryptedThroughputKBps):F1} KB/s** | **{(segment.EncryptionOverhead / segment.UnencryptedAverageParseTime * 100):F1}%** |");
                    sb.AppendLine();
                }

                // 压缩对比
                if (segment.CompressedCount > 0 && segment.UncompressedCount > 0)
                {
                    sb.AppendLine("#### 🗜️ 压缩状态对比");
                    sb.AppendLine("| 状态 | 测试次数 | 平均时间 | 移动平均 | 吞吐量 | 平均大小 | 压缩比 |");
                    sb.AppendLine("|-----|---------|---------|---------|--------|---------|-------|");
                    sb.AppendLine($"| 压缩 | {segment.CompressedCount:N0} | {segment.CompressedAverageParseTime:F3} ms | {segment.CompressedMovingAverageParseTime:F3} ms | {segment.CompressedThroughputKBps:F1} KB/s | {segment.CompressedAverageDataSize:F0} 字节 | - |");
                    sb.AppendLine($"| 不压缩 | {segment.UncompressedCount:N0} | {segment.UncompressedAverageParseTime:F3} ms | {segment.UncompressedMovingAverageParseTime:F3} ms | {segment.UncompressedThroughputKBps:F1} KB/s | {segment.UncompressedAverageDataSize:F0} 字节 | - |");
                    sb.AppendLine($"| **差异** | - | **+{segment.CompressionOverhead:F3} ms** | - | **{(segment.CompressedThroughputKBps - segment.UncompressedThroughputKBps):F1} KB/s** | **-{(segment.UncompressedAverageDataSize - segment.CompressedAverageDataSize):F0} 字节** | **{segment.CompressionRatio:F1}%** |");
                    sb.AppendLine();
                }
            }
        }

        /// <summary>
        /// 添加结论和建议
        /// </summary>
        private void AppendConclusionsAndRecommendations(StringBuilder sb)
        {
            sb.AppendLine("## 💡 测试结论与性能分析");
            sb.AppendLine();

            sb.AppendLine("### 主要发现");
            var findings = GenerateFindings();
            foreach (var finding in findings)
            {
                sb.AppendLine($"- {finding}");
            }
            sb.AppendLine();

            sb.AppendLine("### 性能优化建议");
            var recommendations = GenerateRecommendations();
            foreach (var recommendation in recommendations)
            {
                sb.AppendLine($"- {recommendation}");
            }
            sb.AppendLine();

            sb.AppendLine("### 测试总结");
            sb.AppendLine($"本次测试共进行了 **{_stats.TotalTests:N0}** 次性能测试，");
            sb.AppendLine($"测试成功率达到 **{_stats.SuccessRate:P2}**，");
            sb.AppendLine($"平均吞吐量为 **{_stats.TestsPerSecond:F1} 测试/秒**。");
            sb.AppendLine();
            sb.AppendLine("测试数据表明 DeviceCommons 库在各种场景下都表现出良好的性能特征，");
            sb.AppendLine("千次移动平均算法有效地平滑了性能数据波动，提供了更稳定的性能基准。");
            sb.AppendLine();

            sb.AppendLine("---");
            sb.AppendLine($"*报告生成时间: {DateTime.Now:yyyy年MM月dd日 HH:mm:ss}*");
            sb.AppendLine("*DeviceCommons 性能测试工具自动生成*");
        }

        /// <summary>
        /// 生成JSON格式的详细数据报告
        /// </summary>
        private void GenerateJsonReport(string timestamp)
        {
            var jsonFileName = $"TestData_{timestamp}.json";
            var jsonFilePath = Path.Combine(_recordsDirectory, jsonFileName);

            var jsonData = new
            {
                TestInfo = new
                {
                    StartTime = _testStartTime,
                    EndTime = DateTime.Now,
                    TotalRunTime = (DateTime.Now - _testStartTime).TotalSeconds,
                    Configuration = new
                    {
                        TestMode = GetTestModeName(),
                        EncryptionProbability = _settings.Test.EncryptionProbability,
                        CompressionProbability = _settings.Test.CompressionProbability,
                        IntervalMs = _settings.Test.IntervalMs
                    }
                },
                OverallStats = new
                {
                    TotalTests = _stats.TotalTests,
                    SuccessCount = _stats.SuccessCount,
                    SuccessRate = _stats.SuccessRate,
                    TestsPerSecond = _stats.TestsPerSecond
                },
                PerformanceStats = new
                {
                    Build = new { Average = _stats.AverageBuildTime, MovingAverage = _stats.MovingAverageBuildTime },
                    Serialize = new { Average = _stats.AverageSerializeTime, MovingAverage = _stats.MovingAverageSerializeTime },
                    Parse = new { Average = _stats.AverageParseTime, MovingAverage = _stats.MovingAverageParseTime }
                },
                SystemResources = new
                {
                    CPU = new { Average = _stats.AverageCpuUsage, MovingAverage = _stats.MovingAverageCpuUsage },
                    Memory = new { Average = _stats.AverageMemoryUsageMB, MovingAverage = _stats.MovingAverageMemoryUsageMB }
                },
                SegmentStats = _stats.GetParseTimeSegmentStats().ToArray()
            };

            var jsonOptions = new JsonSerializerOptions { WriteIndented = true };
            var jsonString = JsonSerializer.Serialize(jsonData, jsonOptions);
            File.WriteAllText(jsonFilePath, jsonString, Encoding.UTF8);
        }

        private string GetTestModeName()
        {
            if (_settings.Test.IntervalMs == 0 && _settings.Test.EncryptionProbability == 1.0) return "压力测试模式";
            if (_settings.Test.IntervalMs == 0 && _settings.Test.EncryptionProbability > 0.6) return "高强度模式";
            if (_settings.Test.IntervalMs > 5) return "低强度模式";
            return "标准模式";
        }

        private static string FormatTimeSpan(TimeSpan timeSpan)
        {
            if (timeSpan.TotalDays >= 1) return $"{timeSpan.Days}天 {timeSpan.Hours}小时 {timeSpan.Minutes}分钟";
            if (timeSpan.TotalHours >= 1) return $"{timeSpan.Hours}小时 {timeSpan.Minutes}分钟 {timeSpan.Seconds}秒";
            if (timeSpan.TotalMinutes >= 1) return $"{timeSpan.Minutes}分钟 {timeSpan.Seconds}秒";
            return $"{timeSpan.Seconds}秒";
        }

        private List<string> GenerateFindings()
        {
            var findings = new List<string>();
            
            if (_stats.SuccessRate >= 0.99)
                findings.Add($"✅ 系统稳定性优秀，测试成功率达到{_stats.SuccessRate:P2}");
            else if (_stats.SuccessRate >= 0.95)
                findings.Add($"✅ 系统稳定性良好，测试成功率为{_stats.SuccessRate:P2}");
            else
                findings.Add($"⚠️ 系统稳定性需要关注，测试成功率仅为{_stats.SuccessRate:P2}");

            if (_stats.EncryptedCount > 0 && _stats.UnencryptedCount > 0)
            {
                var encOverhead = (_stats.EncryptionOverhead / _stats.UnencryptedAverageTime * 100);
                findings.Add($"🔐 加密平均增加 {encOverhead:F1}% 的性能开销");
            }

            if (_stats.CompressedCount > 0 && _stats.UncompressedCount > 0)
            {
                var compRatio = (1 - _stats.CompressedAverageSize / _stats.UncompressedAverageSize) * 100;
                findings.Add($"🗜️ 压缩平均节省 {compRatio:F1}% 的存储空间");
            }

            findings.Add($"📊 千次移动平均有效平滑了性能波动，提供稳定的性能基准");

            return findings;
        }

        private List<string> GenerateRecommendations()
        {
            var recommendations = new List<string>();
            
            if (_stats.AverageCpuUsage > 80)
                recommendations.Add("⚠️ CPU使用率较高，建议优化算法或增加计算资源");
            
            if (_stats.AverageMemoryUsageMB > 500)
                recommendations.Add("⚠️ 内存使用量较大，建议检查内存泄漏或优化内存管理");

            var segmentStats = _stats.GetParseTimeSegmentStats().ToList();
            var largeSegment = segmentStats.FirstOrDefault(s => s.Segment == DataSizeSegment.Large || s.Segment == DataSizeSegment.ExtraLarge);
            if (largeSegment != null && largeSegment.AverageParseTime > 5.0)
                recommendations.Add("📈 大消息解析耗时较长，建议考虑消息分片或并行处理");

            recommendations.Add("🔧 定期监控移动平均趋势，及时发现性能退化");
            recommendations.Add("🎯 基于分段统计结果优化不同大小消息的处理策略");

            return recommendations;
        }
    }
}